"""
字段审核API端点

提供同步和流式字段审核接口
"""

from fastapi import APIRouter, HTTPException, status
from fastapi.responses import StreamingResponse
from loguru import logger
import json
import asyncio
import time
import uuid

from src.schemas.audit import (
    AuditRequest,
    AuditResponse,
    AuditData,
    AuditStatus,
    AuditSummary,
    StreamEvent,
    TaskStartEvent,
    AuditProgressEvent,
    AuditCompleteEvent,
    TaskCompleteEvent,
    ErrorEvent
)
from src.schemas.base import success_response
from src.services.audit.service import AuditService


router = APIRouter(prefix="/audit", tags=["规则审核"])


# 创建审核服务实例
audit_service = AuditService()


@router.post(
    "/sync",
    response_model=AuditResponse,
    summary="同步规则审核",
    description="""
    对用户确认的字段和附件进行规则审核，返回完整审核结果。
    支持数据交叉验证、字段值内容审核、字段值交叉验证等多种审核类型。
    
    **处理流程：**
    1. 根据audit_type查找规则配置
    2. 检查附件是否已解析（哈希缓存）
    3. 如未解析，执行字段提取和溯源
    4. 遍历审核规则，构建LLM请求参数
    5. 调用LLM审核agent
    6. 返回审核结果和汇总
    
    **缓存机制：**
    - 系统会自动检查相同附件是否已解析过
    - 如果已解析，直接复用提取结果，加速审核
    
    **超时控制：**
    - 如果处理时间超过timeout，将返回taskId供后续查询
    - 任务会继续在后台执行，结果会保存到任务存储中
    """
)
async def audit_fields_sync(request: AuditRequest) -> AuditResponse:
    """
    同步字段审核
    
    Args:
        request: 审核请求
        
    Returns:
        AuditResponse: 审核响应
        
    Raises:
        HTTPException: 审核失败时抛出异常
    """
    try:
        logger.info(f"收到同步审核请求: audit_type={request.audit_type}, "
                   f"fields_count={len(request.confirmed_fields)}, "
                   f"files_count={len(request.files)}, "
                   f"timeout={request.timeout}ms")
        
        # 将超时时间从毫秒转换为秒
        timeout_seconds = request.timeout / 1000 if request.timeout else 300
        
        # 生成任务ID（确保在创建任务前就有ID）
        # 为审核任务添加前缀，避免与提取任务冲突
        base_task_id = request.task_id or request.request_id or f"task_{uuid.uuid4().hex[:16]}"
        task_id = f"audit_{base_task_id}"
        
        # 创建带task_id的请求对象（任务将在Service层创建）
        request_with_task = AuditRequest(
            task_id=task_id,
            audit_type=request.audit_type,
            confirmed_fields=request.confirmed_fields,
            files=request.files,
            rule_config_id=request.rule_config_id,
            timeout=request.timeout,
            request_id=request.request_id
        )
        
        # 创建任务（不使用 wait_for，避免超时后被取消）
        audit_task = asyncio.create_task(
            audit_service.audit_fields(request_with_task, enable_cache=True)
        )
        
        # 使用 wait 等待任务完成或超时，但不取消任务
        done, pending = await asyncio.wait(
            {audit_task},
            timeout=timeout_seconds,
            return_when=asyncio.FIRST_COMPLETED
        )
        
        if done:
            # 任务在超时前完成
            audit_data = audit_task.result()
            
            logger.info(f"审核完成: request_id={request.request_id}, "
                       f"total={audit_data.summary.total}, "
                       f"passed={audit_data.summary.passed}, "
                       f"failed={audit_data.summary.failed}, "
                       f"pending={audit_data.summary.pending}")
            
            # 替换task_id为原始ID（不带前缀）
            audit_data_dict = audit_data.model_dump()
            if audit_data_dict.get("task_id"):
                audit_data_dict["task_id"] = base_task_id
            
            # 包装响应
            return success_response(
                data=audit_data_dict,
                message="success"
            )
        else:
            # 超时，但任务继续在后台运行
            logger.warning(f"审核超时，任务转为后台继续执行: task_id={task_id}, "
                          f"timeout={timeout_seconds}s")
            
            # 返回 PENDING 状态和 task_id（返回原始task_id，不带前缀）
            # 任务会继续在后台执行，结果会保存到 task_store
            pending_data = AuditData(
                task_id=base_task_id,  # 返回原始task_id，不带前缀
                status=AuditStatus.PROCESSING,
                audit_type=request.audit_type,
                confirmed_fields=request.confirmed_fields,
                audit_results=[],
                summary=AuditSummary(
                    total=0,
                    passed=0,
                    failed=0,
                    pending=0,
                    manual_review=0
                ),
                processing_time_ms=int(timeout_seconds * 1000)
            )
            
            return success_response(
                data=pending_data.model_dump(),
                message="任务处理中，请稍后查询结果"
            )
        
    except ValueError as e:
        logger.error(f"审核参数错误: {e}")
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e)
        )
    except Exception as e:
        logger.error(f"审核失败: {e}", exc_info=True)
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"审核失败: {str(e)}"
        )


@router.post(
    "/stream",
    summary="流式规则审核",
    description="""
    使用Server-Sent Events (SSE)流式返回审核结果。
    每完成一条审核规则就推送一次结果。
    
    **事件类型：**
    - task_start: 任务开始
    - audit_progress: 审核进度（可选）
    - audit_complete: 单个审核规则完成
    - task_complete: 所有审核完成
    - error: 错误事件
    
    **使用场景：**
    - 审核规则较多，希望实时看到进展
    - 需要在前端显示进度条
    - 长时间审核任务
    """
)
async def audit_fields_stream(request: AuditRequest):
    """
    流式字段审核
    
    Args:
        request: 审核请求
        
    Returns:
        StreamingResponse: SSE事件流
    """
    try:
        logger.info(f"收到流式审核请求: audit_type={request.audit_type}")
        
        async def event_generator():
            """生成SSE事件流"""
            try:
                # 发送任务开始事件
                yield f"event: task_start\n"
                yield f"data: {json.dumps({'task_id': request.request_id or request.task_id, 'audit_type': request.audit_type}, ensure_ascii=False)}\n\n"
                
                # TODO: 实现流式审核逻辑
                # 这里需要修改 audit_service 支持流式返回
                # 暂时使用同步方式，然后流式推送结果
                
                audit_data = await audit_service.audit_fields(
                    request=request,
                    enable_cache=True
                )
                
                # 逐个推送审核结果
                for i, result in enumerate(audit_data.audit_results):
                    # 发送进度事件
                    progress = (i + 1) / len(audit_data.audit_results)
                    yield f"event: audit_progress\n"
                    yield f"data: {json.dumps({'current': i + 1, 'total': len(audit_data.audit_results), 'progress': progress}, ensure_ascii=False)}\n\n"
                    
                    # 发送审核完成事件
                    yield f"event: audit_complete\n"
                    yield f"data: {json.dumps(result.model_dump(), ensure_ascii=False)}\n\n"
                
                # 发送任务完成事件
                yield f"event: task_complete\n"
                yield f"data: {json.dumps({'status': 'completed', 'summary': audit_data.summary.model_dump()}, ensure_ascii=False)}\n\n"
                
            except Exception as e:
                logger.error(f"流式审核失败: {e}", exc_info=True)
                yield f"event: error\n"
                yield f"data: {json.dumps({'error_message': str(e)}, ensure_ascii=False)}\n\n"
        
        return StreamingResponse(
            event_generator(),
            media_type="text/event-stream",
            headers={
                "Cache-Control": "no-cache",
                "Connection": "keep-alive",
                "X-Accel-Buffering": "no"
            }
        )
        
    except Exception as e:
        logger.error(f"启动流式审核失败: {e}", exc_info=True)
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"启动流式审核失败: {str(e)}"
        )


